#pragma once

#include <libev/ev.h>


struct ev_loop;


namespace xrtc {

class EventLoop;
class IOWatcher;
class TimerWatcher;

using io_cb_t = void(*)(EventLoop* el, IOWatcher* w, int fd, int events, void* data);
using time_cb_t = void (*)(EventLoop* el, TimerWatcher* w, void* data);

class IOWatcher {
public:
    IOWatcher(EventLoop* el, io_cb_t cb, void* data) : m_el(el), m_cb(cb), m_data(data) {
        m_io.data = this;   
    }

public:
    EventLoop* m_el;
    ev_io m_io;
    io_cb_t m_cb;
    void* m_data;
};

class TimerWatcher {
public:
    TimerWatcher(EventLoop* el, time_cb_t cb, void* data, bool repeat) 
        : m_el(el), m_cb(cb), m_data(data), m_repeat(repeat) {  
        m_timer.data = this;
    }

public:
    EventLoop* m_el;
    struct ev_timer m_timer;
    time_cb_t m_cb;
    void* m_data;
    bool m_repeat;
};

class EventLoop {
public:
    enum {
        READ = 0X01,
        WRITE= 0x02
    };

    EventLoop(void *owner);
    ~EventLoop();

    void start();
    void stop();

    void* owner() { return m_owner; }
    unsigned long now() { return static_cast<unsigned long>(ev_now(m_loop) * 1000000); }

    // 创建IO事件
    IOWatcher* createIOEvent(io_cb_t cb, void* data);
    // 启动并添加事件
    void startIOEvent(IOWatcher* w, int fd, int mask);
    // 停止并删除事件
    void stopIOEvent(IOWatcher* w, int fd, int mask);
    // 关闭并删除事件
    void deleteIOEvent(IOWatcher* w);

    // 创建定时器
    TimerWatcher* createTimer(time_cb_t cb, void* data, bool need_repeat);
    void startTimer(TimerWatcher* w, unsigned int usec);
    void stopTimer(TimerWatcher* w);
    void deleteTimer(TimerWatcher* w);

private:
    void* m_owner;          // 事件循环的拥有者
    struct ev_loop* m_loop; // 事件循环
};
} // namespace xrtc